home *** CD-ROM | disk | FTP | other *** search
- **
- ** ProNET.DEVICE Version 2 ©1995 by Michael Krause
- ** Most parts totally recoded, only few parts left from V1
- **
- ** 05-05-95 Started
- ** 08-05-95 v35.0
- ** 31-05-95 If the pending writes list is not empty before the MainLoop
- ** Wait(), we will signal ourselves to call msgREAD! This is
- ** because otherwise a timeout while sending would cause the
- ** device to hang completely, if the other machine doesn't
- ** send something! v35.1
- ** 05-06-95 Flags Argument for Driver-Init. v35.2
- ** 09-06-95 Getconfigstring uses MEMF_PUBLIC for Read Buffer. v35.3
- ** 15-06-95 PNDERR_DRIVERTROUBLE introduced. v35.4
-
- VERSION equ 35
- REVISION equ 4
-
- DEBUG equ 0
-
- include "A:OSmacros.i"
- include "exec/exec.i"
- include "dos/dosextens.i"
- include "A:ProNET/include/devices/pronet.i"
- include "exec_lib.i"
- include "dos_lib.i"
-
- moveq #-1,d0
- rts
-
- ** -----------------------------------------------------------------------
- **
- **
- **
- **
-
- **
- ** Library/Device Base Structures
- **
-
- **
- **
- **
- **
- ** -----------------------------------------------------------------------
-
- STRUCTURE MyDev,LIB_SIZE ;Device Base
- APTR pnd_SegList
- APTR pnd_DosBase
- LABEL pnd_SizeOf
-
- STRUCTURE MyUnit,0 ;Unit Structure
- APTR pndu_Next
- ULONG pndu_UnitNr
- APTR pndu_ProcessID
- APTR pndu_MsgPort
- LABEL pndu_SizeOf
-
- STRUCTURE PortMember,0 ;One Port of a Unit
- APTR pndp_Next
- UWORD pndp_PortNr
- ULONG pndp_MsgPort
- LABEL pndp_SizeOf
-
- PND_ADDPORT equ 5
- PND_REMPORT equ 6
-
- LibResident dc.w RTC_MATCHWORD
- dc.l LibResident
- dc.l EndResident
- dc.b RTF_AUTOINIT
- dc.b VERSION
- dc.b NT_DEVICE
- dc.b 0
- dc.l DevName
- dc.l IDString
- dc.l LibInitData
-
- DevName dc.b "pronet.device",0
- dc.b "$VER: "
- IDString dc.b "pronet.device "
- dc.b (VERSION/10)+48,(VERSION-((VERSION/10)*10))+48,".",REVISION+48
- dc.b " (09-06-95)",13,10,0
- even
-
- LibInitData dc.l pnd_SizeOf
- dc.l FuncTab
- dc.l DataTab
- dc.l LibInitRout
-
- FuncTab dc.l Open
- dc.l Close
- dc.l Expunge
- dc.l ExtFunc
- dc.l BeginIO
- dc.l AbortIO
- dc.l getconfigstr
- dc.l freeconfigstr
- dc.l -1
-
- DataTab INITBYTE LN_TYPE,NT_DEVICE
- INITLONG LN_NAME,DevName
- INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
- INITWORD LIB_VERSION,VERSION
- INITWORD LIB_REVISION,REVISION
- INITLONG LIB_IDSTRING,IDString
- dc.w 0
-
- OurBase dc.l 0
-
- ** -----------------------------------------------------------------------
- **
- **
- **
- **
-
- **
- ** Library/Device Base Routines
- **
-
- **
- **
- **
- **
- ** -----------------------------------------------------------------------
-
- ; -- Called once when the device was loaded
- LibInitRout movem.l d1-d7/a0-a6,-(sp)
- move.l d0,a5
- move.l a5,OurBase
- move.l a0,pnd_SegList(a5)
-
- lea dosname(pc),a1
- moveq #0,d0
- LIBCALL OpenLibrary
- move.l d0,pnd_DosBase(a5)
-
- move.l a5,d0
- movem.l (sp)+,d1-d7/a0-a6
- rts
-
- ; -- This piece is called by OpenDevice()
- Open movem.l a2-a6/d2-d7,-(sp)
- addq.w #1,LIB_OPENCNT(a6)
- move.l d0,d6 ;Unit
- move.l a1,a2 ;IORequest
- move.l a6,a5 ;DevBase
-
- move.b #IOERR_OPENFAIL,IO_ERROR(a2)
-
- * Does the required Unit already exist?
- lea unitlist(pc),a3
- .searchunit move.l (a3),d0
- beq.s .newunit
- move.l d0,a3
- cmp.l pndu_UnitNr(a3),d6
- bne.s .searchunit
- bra.s .unitok
-
- * No! So create a Unit!
- .newunit bsr InitUnit
- tst.l d0
- beq .ende
- move.l d0,a3
-
- * Yes! Add new port now! Unit-Structure in a3
- .unitok move.l 4.w,a6
- move.w #PND_ADDPORT,IO_COMMAND(a2)
- move.l a2,a1
- move.l pndu_MsgPort(a3),a0
- LIBCALL PutMsg
- move.l a2,a1
- LIBCALL WaitIO
- tst.b d0
- bne.s .ende
-
- move.l a3,IO_UNIT(a2)
-
- * Device successfully opened.
- move.l a5,a6
- bclr #LIBB_DELEXP,LIB_FLAGS(a6)
- addq.w #1,LIB_OPENCNT(a6)
- move.b #NT_REPLYMSG,LN_TYPE(a2)
- clr.b IO_ERROR(a2)
-
- .ende move.l a5,a6
- subq.w #1,LIB_OPENCNT(a6)
- move.b IO_ERROR(a2),d0
- beq.s .0
- move.l #-1,IO_DEVICE(a2)
- .0 movem.l (sp)+,a2-a6/d2-d7
- rts
-
- ; -- Called by CloseDevice()
- Close movem.l a2/a5,-(sp)
- move.l a1,a2
- move.l a6,a5
-
- move.l 4.w,a6
- move.l IO_UNIT(a1),a0
- move.l pndu_MsgPort(a0),a0
- move.w #PND_REMPORT,IO_COMMAND(a1)
- LIBCALL PutMsg
- move.l a2,a1
- LIBCALL WaitIO
-
- move.l a2,a1
- move.l a5,a6
- move.l #-1,IO_DEVICE(a1)
- move.l #-1,IO_UNIT(a1)
-
- subq.w #1,LIB_OPENCNT(a6)
- moveq #0,d0
- movem.l (sp)+,a2/a5
- rts
-
- ; -- This routine was kept free by Commodore for about 10 years now ;)
- ExtFunc moveq #0,d0
- rts
-
- ; -- Application wants an IORequest to be executed
- BeginIO move.l a6,-(sp)
- move.b #NT_MESSAGE,LN_TYPE(a1)
- bclr #0,IO_FLAGS(a1) ;Clear IOF_QUICK
- clr.b IO_ERROR(a1)
- move.l IO_UNIT(a1),a0
- move.l pndu_MsgPort(a0),a0
- move.l 4.w,a6
- LIBCALL PutMsg
- moveq #0,d0
- move.l (sp)+,a6
- rts
-
- ; -- AbortIO is not supported
- AbortIO moveq #0,d0 ;Gar nix geht ab hier.
- rts
-
- ; -- Called e.g. when memory is low and the device is not used anymore.
- Expunge movem.l d1-d2/a1-a6,-(sp)
- moveq #0,d0
- bset #LIBB_DELEXP,LIB_FLAGS(a6) ;we don't support
- movem.l (sp)+,d1-d2/a1-a6 ;expunging!
- rts
-
- ; -- Create new Unit
- InitUnit ; a5 *DevBase
- ; a2 *IORequest
- ; d6 Unit
- ; RETURNS d0 *Unit-Structure or NULL
- move.l 4.w,a6
- moveq #pndu_SizeOf,d0
- moveq #MEMF_PUBLIC,d1
- LIBCALL AllocMem
- tst.l d0
- beq.s .ende
- move.l d0,a3
-
- move.l d6,pndu_UnitNr(a3)
-
- * First, create Unit process
- move.l pnd_DosBase(a5),a6 ;We will break the Forbid()
- move.l #DevName,d1 ;which EXEC made for us;
- moveq #0,d2 ;it's okay because we have
- move.l #ProcessCode-4,d3 ;all variables in registers,
- lsr.l #2,d3 ;so our routine can be run
- move.l #4096,d4 ;twice at one time without
- LIBCALL CreateProc ;problems!
- move.l d0,d7
- beq.s .ende
-
- move.l d7,pndu_ProcessID(a3)
-
- * Notify process about Unit number
- move.l 4.w,a6
- move.l a2,a1
- move.l a3,pnr_Data2(a1)
- move.b IO_ERROR(a2),d2 ;save it for the main routine
- move.l d7,a0
- LIBCALL PutMsg
-
- * Wait for Process to finish initialization
- move.l a2,a1
- LIBCALL WaitIO
- move.b d2,IO_ERROR(a2)
- tst.b d0
- bne.s .error
-
- * Now add this Unit-Structure to our internal List!!
- LIBCALL Forbid ;<< important!
- lea unitlist(pc),a0
- move.l (a0),(a3)
- move.l a3,(a0)
- LIBCALL Permit
-
- move.l a3,d0
- rts
-
- .error move.l 4.w,a6 ;Process will terminate
- move.l a3,a1 ;itself in case of an error
- moveq #pndu_SizeOf,d0
- LIBCALL FreeMem
- .ende moveq #0,d0
- rts
-
- unitlist dc.l 0 ;List of all Units loaded!
-
- ** -----------------------------------------------------------------------
- **
- **
- **
- **
-
- **
- ** DeviceUnit Process Code
- **
-
- **
- **
- **
- **
- ** -----------------------------------------------------------------------
-
- cnop 0,4
-
- STRUCTURE PrivateData,0
- APTR priv_OurUnit
- STRUCT priv_ConfigStringName,30
- APTR priv_ConfigString
- STRUCT priv_DriverName,30
-
- LABEL priv_DriverData
- UBYTE priv_ReadSignalBit
- UBYTE priv_pad0
- APTR priv_ReadQuery
- APTR priv_Read
- APTR priv_Write
-
- APTR priv_MsgPort
- APTR priv_MsgBackPort
- APTR priv_PortList
- STRUCT priv_PendingReads,12
- STRUCT priv_PendingWrites,12
- LABEL priv_SizeOf
-
- ProcessCode move.l 4.w,a6
- move.l ThisTask(a6),a2
- lea pr_MsgPort(a2),a2
- move.l a2,a0
- LIBCALL WaitPort
- move.l a2,a0
- LIBCALL GetMsg
- move.l d0,a3
-
- move.b #IOERR_OPENFAIL,IO_ERROR(a3) ;[a3] Startupmsg
-
- * Get memory for private data
- moveq #priv_SizeOf,d0
- move.l #MEMF_CLEAR,d1
- LIBCALL AllocMem
- tst.l d0
- beq .ende
- move.l d0,a5
-
- lea priv_PendingReads(a5),a1
- NEWLIST a1
- lea priv_PendingWrites(a5),a1
- NEWLIST a1
-
- * Get port for messages replied from the application
- bsr CreatePort
- move.l d0,priv_MsgBackPort(a5)
- beq.s .noconf
-
- bsr CreatePort
- move.l d0,priv_MsgPort(a5)
- beq.s .noport2
-
- move.l pnr_Data2(a3),a0
- move.l a0,priv_OurUnit(a5)
- move.l priv_MsgPort(a5),pndu_MsgPort(a0)
-
- * Get configuration string for our unit
- move.l pndu_UnitNr(a0),d0
- lea confstr(pc),a1
- lea priv_ConfigStringName(a5),a0
- .l0 move.b (a1)+,(a0)+
- bne.s .l0
- subq.l #1,a0
- bsr long2dec
- move.b #":",(a0)+
- clr.b (a0)
- lea priv_ConfigStringName(a5),a0
- bsr getconfigstr
- move.l d0,priv_ConfigString(a5)
- beq.s .noconf
-
- move.b #PNDERR_DRIVERTROUBLE,IO_ERROR(a3)
- bsr StartDriver
- tst.l d0
- beq.s .noconf
-
- clr.b IO_ERROR(a3)
- move.l a3,a1
- LIBCALL ReplyMsg
-
- bra MainLoop
-
- .noport2 move.l priv_MsgBackPort(a5),a0
- bsr DeletePort
- .noconf move.l a5,a1
- moveq #priv_SizeOf,d0
- LIBCALL FreeMem
- .ende move.l a3,a1
- LIBCALL ReplyMsg
- rts
-
- confstr dc.b "pronet-device-",0
- even
-
- ; -- Load the interface driver and initialize it.
- StartDriver ; RETURNS d0 NULL on failure!
- movem.l a2/a6,-(sp)
- lea priv_DriverName(a5),a1
- move.l a1,d1
- lea drivername(pc),a0
- .l0 move.b (a0)+,(a1)+
- bne.s .l0
- subq.l #1,a1
- move.l priv_ConfigString(a5),a0
- .l1 move.b (a0)+,d0
- move.b d0,(a1)+
- cmp.b #" ",d0
- bhi.s .l1
- clr.b -(a1)
- move.l a0,d6
-
- move.l OurBase(pc),a6 ;naahh why should I open
- move.l pnd_DosBase(a6),a6 ;it again??
- LIBCALL LoadSeg
- add.l d0,d0
- add.l d0,d0
- beq.s .error
- addq.l #4,d0
- move.l d0,a2
-
- * And now, Ladies & Gentlemen :))
- lea priv_DriverData(a5),a0
- move.l d6,a1 ;ConfString after Driver-ID
- move.l #"RST!",d0
- moveq #0,d1
- jsr (a2)
- tst.l d0
- beq.s .error
-
- moveq #-1,d0
- bra.s .ende
-
- .error moveq #0,d0
- .ende movem.l (sp)+,a2/a6
- rts
-
- drivername dc.b "DEVS:ProNET/",0
- even
-
-
- ******************
- ; -- The Main Loop
- ******************
-
- MainLoop move.l priv_MsgBackPort(a5),a0
- move.b MP_SIGBIT(a0),d2
- move.b priv_ReadSignalBit(a5),d3
- move.l priv_MsgPort(a5),a0
- move.b MP_SIGBIT(a0),d4
- moveq #0,d5
- bset d2,d5
- bset d3,d5
- bset d4,d5 ;[d5] Signalmask to wait for
- movem.l a6/d2-d5,-(sp)
-
- Wait4Msg movem.l (sp),a6/d2-d5
- bsr CheckWrites
- move.l d5,d0
- LIBCALL Wait
- movem.l d0/d3/d4,-(sp)
- btst d2,d0
- bne doMSGBACK
- wait1 movem.l (sp),d0/d3/d4
- btst d3,d0
- bne doREAD
- wait2 movem.l (sp)+,d0/d3/d4
- btst d4,d0
- bne doMSG
- bra Wait4Msg
-
- ; -- New Message at our MsgPort
- doMSG move.l priv_MsgPort(a5),a0
- LIBCALL GetMsg
- tst.l d0
- beq Wait4Msg ;no more messages
- move.l d0,a2
- move.w IO_COMMAND(a2),d0
-
- cmp.w #PND_WRITE,d0
- beq doWRITE
- cmp.w #PND_ADDPORT,d0
- beq doADDPORT
- cmp.w #PND_REMPORT,d0
- beq doREMPORT
-
- move.b #IOERR_NOCMD,IO_ERROR(a2)
- move.l a2,a1
- LIBCALL ReplyMsg
- bra doMSG
-
- ; -- Add a new port to this unit
- doADDPORT move.w pnr_NetSourcePort(a2),d1
- cmp.w #-1,d1
- beq addport_getconf
- cmp.w #-2,d1
- beq addport_getnext
-
- move.b #IOERR_OPENFAIL,IO_ERROR(a2)
-
- * See if port already exists, portnumber in d1 now
- lea priv_PortList(a5),a0
- .loop0 move.l (a0),d0
- beq.s .ok
- move.l d0,a0
- cmp.w pndp_PortNr(a0),d1
- bne.s .loop0
- * Sorry
- move.b #PNDERR_PORTEXISTS,IO_ERROR(a2)
- bra.s addport_ende
-
- * No, add it!
- .ok moveq #pndp_SizeOf,d0
- moveq #0,d1
- LIBCALL AllocMem
- tst.l d0
- beq.s addport_ende
-
- move.l d0,a4
- move.w pnr_NetSourcePort(a2),pndp_PortNr(a4)
- move.l pnr_MsgPort(a2),pndp_MsgPort(a4)
- lea priv_PortList(a5),a0
- move.l (a0),(a4)
- move.l a4,(a0)
-
- bsr TryPendingReads
-
- clr.b IO_ERROR(a2) ;Okay, port added
- addport_ende move.l a2,a1
- LIBCALL ReplyMsg
- bra doMSG
-
- addport_getconf move.l pnr_Data1(a2),a0
- bsr getconfigstr
- move.l d0,d3
- beq.s .nostring
- move.l d0,a0
- bsr dec2long
- move.w d1,pnr_NetSourcePort(a2)
- move.l d3,a0
- bsr freeconfigstr
- bra doADDPORT
- .nostring move.b #PNDERR_BADCONFIG,IO_ERROR(a2)
- bra.s addport_ende
-
- addport_getnext moveq #1,d1
- lea priv_PortList(a5),a1
- .next move.l a1,a0
- .loop0 move.l (a0),d0
- beq.s .notfound
- move.l d0,a0
- cmp.w pndp_PortNr(a0),d1
- bne.s .loop0
- addq.w #1,d1
- bra.s .next
- .notfound move.w d1,pnr_NetSourcePort(a2)
- bra doADDPORT
-
- ; -- Remove current port
- doREMPORT move.w pnr_NetSourcePort(a2),d2
- lea priv_PortList(a5),a1
- .find move.l a1,a3
- move.l (a1),d0
- beq.s .notfound
- move.l d0,a1
- cmp.w pndp_PortNr(a1),d2
- bne.s .find
- move.l (a1),d2
- moveq #pndp_SizeOf,d0
- LIBCALL FreeMem
- move.l d2,(a3) ;Teil aus der Liste entfernt !!
- move.l a2,a1
- LIBCALL ReplyMsg
- .notfound bra doMSG
-
- ; -- Do a WRITE command
- doWRITE move.l a2,a1
- lea priv_PendingWrites(a5),a0
- LIBCALL AddTail
- bsr TryPendingWrites
- bra doMSG ;kurz und schmerzlos :-)
-
- ; -- A ProNET-Message was replied
- doMSGBACK move.l priv_MsgBackPort(a5),a0
- LIBCALL GetMsg
- tst.l d0
- beq wait1
- move.l d0,a1 ;we don't need it any more.
- moveq #0,d0
- move.w MN_LENGTH(a1),d0
- add.l #MN_SIZE,d0
- LIBCALL FreeMem
- bra.s doMSGBACK
-
- ; -- A new message from another Amiga is ready
- doREAD move.l priv_ReadQuery(a5),a0 ;Do external driver magic..
- jsr (a0)
-
- * d0.w length (if NULL then exit!!!)
- * d1 destination port
- * d2 source port
- ext.l d0
- beq.s .ende
- move.w d1,d7
- move.w d2,d5
- move.l d0,d6
- addq.w #2,d6 ;include Source Port word
-
- add.l #MN_SIZE+2,d0
- move.l d0,d3
- .tryagain moveq #MEMF_PUBLIC,d1 ;This part is the one and
- LIBCALL AllocMem ;only thing in this device
- tst.l d0 ;which I don't like, but
- bne.s .memok ;it's the only solution!
- move.l OurBase(pc),a6
- move.l pnd_DosBase(a6),a6
- moveq #50,d1
- LIBCALL Delay
- move.l 4.w,a6
- move.l d3,d0
- bra.s .tryagain
-
- * Now get the data and build a Message
- .memok move.l d0,a3
- lea MN_SIZE+2(a3),a0
- move.l priv_Read(a5),a1
- jsr (a1)
- move.w d5,MN_SIZE(a3)
- move.w d6,MN_LENGTH(a3)
- move.w d7,LN_NAME(a3)
- move.l priv_MsgBackPort(a5),MN_REPLYPORT(a3)
- move.b #NT_MESSAGE,LN_TYPE(a3)
-
- lea priv_PendingReads(a5),a0
- move.l a3,a1
- LIBCALL AddTail
-
- .ende bsr TryPendingReads
- bsr TryPendingWrites
- bra wait2
-
- ***
- ***
- ***
-
- ; -- Look at the history, 31-05-95 for reasons why we do this!
- CheckWrites lea priv_PendingWrites(a5),a0
- TSTLIST a0
- beq.s .okay
- move.b priv_ReadSignalBit(a5),d0
- moveq #0,d1
- bset d0,d1
- moveq #-1,d0
- LIBCALL SetSignal
- .okay rts
-
- ***
- ***
- ***
-
- ; -- Try to send off all pending messages
- TryPendingReads move.l a2,-(sp)
- lea priv_PendingReads(a5),a3
- move.l LH_HEAD(a3),a2
- addq.l #4,a3
- .looop cmp.l a2,a3
- bne.s .doit
- move.l (sp)+,a2
- rts
-
- .doit move.l a2,a4
- move.l LN_SUCC(a2),a2
-
- move.w LN_NAME(a4),d1
- lea priv_PortList(a5),a0
- .find move.l (a0),d0
- beq.s .looop
- move.l d0,a0
- cmp.w pndp_PortNr(a0),d1
- bne.s .find
- move.l pndp_MsgPort(a0),d5
- move.l a4,a1
- LIBCALL Remove
- move.l d5,a0
- move.l a4,a1
- LIBCALL PutMsg
- bra.s .looop
-
- ; -- Try to send off all pending write requests
- TryPendingWrites
- move.l a2,-(sp)
- lea priv_PendingWrites(a5),a3
- move.l LH_HEAD(a3),a2
- addq.l #4,a3
- .looop cmp.l a2,a3
- bne.s .doit
- .busy move.l (sp)+,a2
- rts
-
- .doit move.l a2,a4
- move.l LN_SUCC(a2),a2
-
- move.l pnr_Data1(a4),a0
- move.l pnr_Length1(a4),d0
- addq.l #1,d0 ;round up to word boundary
- bclr #0,d0
- move.l pnr_Data2(a4),a1
- move.l pnr_Length2(a4),d1
- addq.l #1,d1 ;dito
- bclr #0,d1
- move.w pnr_NetDestPort(a4),d2
- move.w pnr_NetSourcePort(a4),d3
- move.l priv_Write(a5),a6
- jsr (a6) ;Again some driver magic..
- move.l 4.w,a6
- tst.w d0
- bne.s .busy
-
- * IORequest done, reply it!
- move.l a4,a1
- LIBCALL Remove
- move.l a4,a1
- LIBCALL ReplyMsg
- bra.s .looop
-
- ** -----------------------------------------------------------------------
- **
- **
- **
- **
-
- **
- ** Routines for handling the configuration file
- **
-
- **
- **
- **
- **
- ** -----------------------------------------------------------------------
-
- ; -- Obtain configuration string
- getconfigstr ; a0 *line-identifier (e.g. 'HD2:') with ':'
- ; RETURNS d0 *line-string or NULL if it doesn't exist
- movem.l d2-d7/a2-a6,-(sp)
- move.l a0,a2
- moveq #0,d4 ;RC
-
- move.l 4.w,a6
- move.l #$104,d0
- moveq #0,d1
- LIBCALL AllocMem
- move.l d0,d6 ;Allocate FIB
- beq .error
- move.l OurBase(pc),a5
- move.l pnd_DosBase(a5),a5
- move.l a5,a6
- move.l #configname,d1
- moveq #ACCESS_READ,d2
- LIBCALL Lock
- move.l d0,d7
- beq .nolock.mem
- move.l d7,d1
- move.l d6,d2
- LIBCALL Examine
- move.l d7,d1
- LIBCALL UnLock ;So we've got the file length
-
- move.l 4.w,a6
- move.l d6,a0
- move.l fib_Size(a0),d0
- addq.l #1,d0
- move.l d0,d5 ;[d5] configmemsize
- move.l #MEMF_PUBLIC^MEMF_CLEAR,d1
- LIBCALL AllocMem
- tst.l d0
- beq .nolock.mem
- move.l d0,a3 ;[a3] configmem
- move.l a3,a4
-
- move.l a5,a6 ;Read file
- move.l #configname,d1
- move.l #MODE_OLDFILE,d2
- LIBCALL Open
- move.l d0,d7
- beq.s .nofile
- move.l d7,d1
- move.l a3,d2
- move.l d5,d3
- subq.l #1,d3
- LIBCALL Read
- move.l d0,d2
- move.l d7,d1
- LIBCALL Close
- cmp.l d2,d3
- bne.s .nofile
-
- .loop move.l a2,a0 ;Search string
- move.l a3,a1
- bsr.s .comparestr
- tst.w d0
- bne.s .next
-
- .search0 move.b (a1)+,d0 ;Skip spaces until first
- beq.s .nofile ;character
- cmp.b #10,d0
- beq.s .nofile
- cmp.b #32,d0
- bls.s .search0
-
- move.l a1,d2 ;Get length of string
- subq.l #1,d2
- moveq #-5,d0
- .search1 move.b (a1)+,d1
- beq.s .searchok
- cmp.b #10,d1
- beq.s .searchok
- dbra d0,.search1
-
- .searchok neg.l d0 ;Extract string
- move.l d0,d3
- move.l 4.w,a6
- moveq #MEMF_PUBLIC,d1
- LIBCALL AllocMem
- tst.l d0
- beq.s .nofile
- move.l d0,a0
- move.l d3,(a0)+
- move.l a0,d4
- move.l d2,a1
- .copyl0 move.b (a1)+,d1
- move.b d1,(a0)+
- beq.s .copyok
- cmp.b #10,d1
- bne.s .copyl0
- .copyok clr.b -(a0)
- bra.s .nofile
-
- .next bsr.s .nextline
- tst.w d0
- beq.s .loop
-
- .nofile move.l 4.w,a6
- move.l a4,a1
- move.l d5,d0
- LIBCALL FreeMem
- .nolock.mem move.l 4.w,a6
- move.l d6,a1
- move.l #$104,d0
- LIBCALL FreeMem
-
- .error move.l d4,d0
- .ende movem.l (sp)+,d2-d7/a2-a6
- rts
-
- .comparestr moveq #0,d0
- .compl0 move.b (a0)+,d1
- move.b (a1)+,d2
- bclr #5,d1
- bclr #5,d2
- cmp.b d1,d2
- bne.s .comperr
- tst.b d1
- beq.s .compok
- bra.s .compl0
- .comperr moveq #-1,d0
- .compok rts
-
- .nextline moveq #0,d0
- move.b (a3)+,d1
- beq.s .nextlerr
- cmp.b #10,d1
- beq.s .nextlok
- bra.s .nextline
- .nextlerr moveq #-1,d0 ;end of file
- .nextlok rts
-
- ; -- Dispose configuration string
- freeconfigstr ; a0 *line-string got by 'getconfigstr'
- move.l a6,-(sp)
- move.l -(a0),d0
- move.l a0,a1
- move.l 4.w,a6
- LIBCALL FreeMem
- move.l (sp)+,a6
- rts
-
- configname dc.b "DEVS:ProNET.config",0
- dosname dc.b "dos.library",0
- even
-
-
- ** -----------------------------------------------------------------------
- **
- **
- **
- **
-
- **
- ** Useful routines
- **
-
- **
- **
- **
- **
- ** -----------------------------------------------------------------------
-
- dec2long ; konvertiert Dezimalstring ab (a0) zu Longword in D1 !!
- moveq #0,d1
- .loop moveq #0,d0
- move.b (a0)+,d0
- sub.b #"0",d0
- cmp.b #9,d0
- bhi.s .oki
- move.l d1,d2
- lsl.l #3,d1
- add.l d2,d1
- add.l d2,d1
- add.l d0,d1
- bra.s .loop
- .oki rts
-
- long2dec ;Converts Long in d0 to Dec-String in (a0)+
- tst.l d0
- bne.s .0
- move.b #"0",(a0)+
- rts
- .0 lea long2asciitab(pc),a1
- moveq #9,d1
- moveq #0,d6
- .1 move.l (a1)+,d2
- move.l d0,d3
- moveq #-1,d4
- .2 move.l d3,d5
- sub.l d2,d3
- cmp.l d5,d3
- dbhi d4,.2
- add.l d2,d3
- move.l d3,d0
- not.w d4
- bne.s .3
- tst.w d6
- beq.s .4
- .3 st d6
- add.b #"0",d4
- move.b d4,(a0)+
- .4 dbra d1,.1
- rts
- long2asciitab dc.l 1000000000,100000000,10000000,1000000,100000
- dc.l 10000,1000,100,10,1
-
- include "A:ProNET/source/devio.s"
-
- EndResident:
-